package com.infolab.aims.web;



import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import com.infolab.aims.GlobalConstant;
import com.infolab.aims.common.AbstractController;
import com.infolab.aims.common.bean.SearchCriteria;
import com.infolab.aims.common.bean.SearchResult;
import com.infolab.aims.common.exception.ResourceNotFoundException;
import com.infolab.aims.domain.Location;
import com.infolab.aims.domain.LocationBean;
import com.infolab.aims.domain.Section;
import com.infolab.aims.domain.SystemCodeType;
import com.infolab.aims.service.intf.LocationService;
import com.infolab.aims.service.intf.SystemCodeService;


@Controller
@RequestMapping("/location")
@SessionAttributes(value=LocationController.SESSION_SEARCH_CRITERIA)
public class LocationController extends AbstractController {
	
	public static final String SESSION_SEARCH_CRITERIA ="searchCriteria";
	public static final String CONTEXT_PATH ="/location";
	public static final String JSP_MAIN_FORM="locationForm";
	public static final String JSP_MAIN_SEARCH="locationSearch";
	public static final String JSP_SYSTEM_CODE_FORM="locationSystemCodeForm";
	Log logger = LogFactory.getLog(getClass());

	@Autowired
	LocationService locationService;
	
	@Autowired
	SystemCodeService systemCodeService;

	
	@RequestMapping(value="systemCode", method = RequestMethod.GET)
	public String createSystemCodeLocation(Model model) {
		SearchCriteria searchCriteria = new SearchCriteria();
		searchCriteria.addSearchCriteria("active", true);  
		searchCriteria.setMaxRow(200);
		SearchResult searchResult = locationService.searchLocation(searchCriteria);
		LocationBean locationBean = new LocationBean();
		initSystemCodeTypeCodes(locationBean);
		locationBean.setLocations(searchResult.getResult());
		model.addAttribute(locationBean);
		return JSP_SYSTEM_CODE_FORM;
	}
	
	@RequestMapping(value="systemCode", method = RequestMethod.POST)
	public String saveSystemCodeLocation(@ModelAttribute LocationBean locationBean, Model model,HttpServletRequest request) {		
		locationBean.setModifiedBy(getCurrentUserName(request));
		locationBean.setDateModified(new Date());
		systemCodeService.updateSystemCodeLocation(locationBean);
		setSuccessMessage(getMessageResources("success.update","Location Configuration"));
		refreshGlobalLocation(request);
		return "redirect:"+CONTEXT_PATH+"/systemCode";	
	}
	
	/**
	 * init the need update SystemCodeTypeCode
	 * @param locationBean
	 * @return
	 */
	private void initSystemCodeTypeCodes(LocationBean locationBean){
		//first RepairTransferLocation
		SearchCriteria searchCriteria = new SearchCriteria();
		searchCriteria.addSearchCriteria("active", true);  
		searchCriteria.addSearchCriteria("systemCodeTypeCode", GlobalConstant.SYSTEM_CODE_TYPE_REPAIR_TRANSFER_LOCATION);
		SystemCodeType type1 = systemCodeService.findSystemCodeType(searchCriteria);
		locationBean.setRepairTransferLocation(StringUtils.split(type1.getSystemCodeTypeValue(), ","));
		//second WorkOrderAdHoc
		searchCriteria = new SearchCriteria();
		searchCriteria.addSearchCriteria("active", true);  
		searchCriteria.addSearchCriteria("systemCodeTypeCode", GlobalConstant.SYSTEM_CODE_TYPE_COMPONENT_ISSUE_MAIN_LOCATION);
		SystemCodeType type2 = systemCodeService.findSystemCodeType(searchCriteria);
		locationBean.setComponentIssueMainLocation(type2.getSystemCodeTypeValue());
		//third WorkOrderFaultLocation
		searchCriteria = new SearchCriteria();
		searchCriteria.addSearchCriteria("active", true);  
		searchCriteria.addSearchCriteria("systemCodeTypeCode", GlobalConstant.SYSTEM_CODE_TYPE_WORKORDER_FAULT_LOCATION);
		SystemCodeType type3 = systemCodeService.findSystemCodeType(searchCriteria);
		locationBean.setWorkOrderFaultLocation(type3.getSystemCodeTypeValue());
		//fouth WorkOrderInVehicleLocation
		searchCriteria = new SearchCriteria();
		searchCriteria.addSearchCriteria("active", true);  
		searchCriteria.addSearchCriteria("systemCodeTypeCode", GlobalConstant.SYSTEM_CODE_TYPE_WORKORDER_INVEHICLE_LOCATION);
		SystemCodeType type4 = systemCodeService.findSystemCodeType(searchCriteria);
		locationBean.setWorkOrderInVehicleLocation(type4.getSystemCodeTypeValue());
		//fifth WorkOrderActiveLocation
		searchCriteria = new SearchCriteria();
		searchCriteria.addSearchCriteria("active", true);  
		searchCriteria.addSearchCriteria("systemCodeTypeCode", GlobalConstant.SYSTEM_CODE_TYPE_WORKORDER_ACTIVE_LOCATION);
		SystemCodeType type5 = systemCodeService.findSystemCodeType(searchCriteria);
		locationBean.setWorkOrderActiveLocation(type5.getSystemCodeTypeValue());
	}	
	
	@RequestMapping(value="create", method = RequestMethod.GET)
	public String createLocation( Model model) {
		
		model.addAttribute(new Location());
		return JSP_MAIN_FORM;
	}
	
	@RequestMapping(value="create",method=RequestMethod.POST)
	public String saveLocation(@ModelAttribute Location location, BindingResult result,Model model,HttpServletRequest request) {

		if (validateLocation(location, result)) {	
			return JSP_MAIN_FORM;
		}
		
		location.setCreatedBy(getCurrentUserName(request));
		
		prepareAuditObject(location, request);
		locationService.createLocation(location);
		
		setSuccessMessage(getMessageResources("success.create","location " + location.getLocationName()));
		
		refreshGlobalLocation(request);
		
		return "redirect:"+CONTEXT_PATH+"/update/" + location.getLocationId();

	}
	
	@RequestMapping(value="update/{id}",method=RequestMethod.POST)
	public String updateLocation(@PathVariable Integer id,@ModelAttribute Location location, BindingResult result,Model model,HttpServletRequest request) {

		if (validateLocation(location, result)) {
			return JSP_MAIN_FORM;
		}
		
		location.setModifiedBy(getCurrentUserName(request));
		
		prepareAuditObject(location, request);
		locationService.updateLocation(location);
		
		setSuccessMessage(getMessageResources("success.update","location " + location.getLocationName()));
		
		refreshGlobalLocation(request);
		
		return "redirect:"+CONTEXT_PATH+"/update/" + location.getLocationId();	
		
	}
	
	@RequestMapping(value={"update/{id}","detail/{id}"}, method = RequestMethod.GET)
	public String detailLocation(@PathVariable Integer id,Model model,HttpServletRequest request) {
		
		Location location = locationService.getLocation(id);
		if(location==null) {
			throw new ResourceNotFoundException("Location " + id);
		}
		
		model.addAttribute(location);
		return JSP_MAIN_FORM;
		
	}
	

	
	@ModelAttribute(LocationController.SESSION_SEARCH_CRITERIA)
	public SearchCriteria getLocationSearchCriteria()
	{
		return new SearchCriteria();
	}
	

	@RequestMapping(value="search")
	public String searchLocation(@ModelAttribute(LocationController.SESSION_SEARCH_CRITERIA) SearchCriteria searchCriteria,@ModelAttribute("currentSearchCriteria") SearchCriteria currentSearchCriteria,Model model) {
		
		if(currentSearchCriteria.getCurPage()!=null)
			searchCriteria.setCurPage(currentSearchCriteria.getCurPage());
		
		searchCriteria.addSearchCriteria("active", true);
		
		SearchResult searchResult = locationService.searchLocation(searchCriteria);
		model.addAttribute(searchResult);
		
		return JSP_MAIN_SEARCH;
	}
	
	@RequestMapping(value={"delete/{id}"}, method = RequestMethod.GET)
	public String deleteLocation(@PathVariable Integer id,Model model,HttpServletRequest request) {
		
		Location location = locationService.getLocation(id);
		
		location.setModifiedBy(getCurrentUserName(request));
		
		prepareAuditObject(location, request);
		locationService.deleteLocation(location);
		
		refreshGlobalLocation(request);
		
		return "redirect:"+CONTEXT_PATH+"/search";
	}
	
	private boolean validateLocation(Location location,BindingResult result)
	{
		if(location.getSection().getSectionId()==null)
			location.setSection(null);
		
		validator.validate(location, result);
		
		if(location.getLocationId()==null) //only for create asset model
		{
			if(!result.hasErrors())
			{
				SearchCriteria searchCriteria = new SearchCriteria();
				searchCriteria.addSearchCriteria("locationCode", location.getLocationCode());
				Location tmp = locationService.findLocation(searchCriteria);
				if(tmp!=null)
					result.rejectValue("locationCode", "error.exist", new String[]{location.getLocationCode()}, "");
			}
		}

		
		return result.hasErrors();
	}
	
	private void prepareAuditObject(Location location, HttpServletRequest request){
		/* audit start */
		Section sec = findSection(request, location.getSection().getSectionId());
		location.setSection(sec);
			
		/* audit end */	
	}
	

	
	
	
}
